package com.itheima.bos.dao.base;

import com.itheima.bos.dao.IBaseDao;
import com.itheima.bos.utils.PageBean;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * Created by Mr.King on 2017/3/7.
 */
public class IBaseDaoImpl<T> extends HibernateDaoSupport implements IBaseDao<T> {

    @Resource
    public void setSF(SessionFactory sessionFactory){
        super.setSessionFactory(sessionFactory);
    }


    private Class<T> domain;

    public IBaseDaoImpl() {
        //获得父类类型
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        //获得泛型数组
        Type[] types = type.getActualTypeArguments();

        domain = (Class<T>) types[0];
    }


    @Override
    public void save(T t) {
        this.getHibernateTemplate().save(t);
    }

    @Override
    public void saveOrUpdate(T t) {
        this.getHibernateTemplate().saveOrUpdate(t);
    }

    @Override
    public void delete(T t) {
        this.getHibernateTemplate().delete(t);
    }

    @Override
    public void update(T t) {
        this.getHibernateTemplate().update(t);
    }

    @Override
    public T findById(Serializable id) {
        return this.getHibernateTemplate().get(domain,id);
    }

    @Override
    public List<T> findAll() {
        String sql = "from "+domain.getSimpleName();
        return (List<T>) this.getHibernateTemplate().find(sql);
    }

    @Override
    public List<T> findCriteria(DetachedCriteria criteria) {
        return (List<T>) this.getHibernateTemplate().findByCriteria(criteria);
    }

    @Override
    public List<T> findNameQuery(String nameQuery, Object... args) {
        return (List<T>) this.getHibernateTemplate().findByNamedQuery(nameQuery,args);
    }

    @Override
    public void executeNameQuery(String nameQuery, Object... args) {
        Session session = this.getHibernateTemplate().getSessionFactory().openSession();
        Query query = session.getNamedQuery(nameQuery);
        if (args != null && args.length > 0){
            int i = 0;
            for (Object obj : args){
                query.setParameter(i++,obj);
            }
        }
        query.executeUpdate();
    }

    @Override
    public void pageQuery(PageBean pageBean) {

        int currentPage = pageBean.getCurrentPage();//当前页数
        int pageSize = pageBean.getPageSize();//每页显示条数
        DetachedCriteria criteria = pageBean.getDetachedCriteria();//离线条件查询

        criteria.setProjection(Projections.rowCount());//发送统计sql语句
        List<Long> count = (List<Long>) this.getHibernateTemplate().findByCriteria(criteria);
        pageBean.setTotal(count.get(0).intValue());

        criteria.setProjection(null);//清空查询格式
        criteria.setResultTransformer(DetachedCriteria.ROOT_ENTITY);//每条数据封装成实体对象

        int begin = (currentPage - 1) * pageSize;

        List recordList = this.getHibernateTemplate().findByCriteria(criteria, begin, pageSize);

        pageBean.setRows(recordList);
    }
}
